package com.quanshu.exchange.support.net.core;


import com.quanshu.exchange.support.net.ApiException;
import com.quanshu.exchange.support.net.loading.ILoading;
import com.quanshu.exchange.support.utils.LogUtil;
import com.quanshu.exchange.ui.widget.LoadingDialog;
import com.trello.rxlifecycle2.LifecycleTransformer;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;

import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;

/**
 * 对事件流做统一变换
 */
public class BaseTransformer<T> implements ObservableTransformer<T, T> {

    private LifecycleTransformer<T> transformer;//绑定Activity的生命周期
    private ILoading loading;//网络进度条

    public BaseTransformer(RxAppCompatActivity rx) {
        this(rx, false, false);
    }

    public BaseTransformer(RxAppCompatActivity rx, boolean hasProgressDialog, boolean isCancelAble) {
        this(rx, hasProgressDialog ? new LoadingDialog(rx, isCancelAble) : null);
    }

    public BaseTransformer(RxAppCompatActivity rx, ILoading loading) {
        this.transformer = rx.bindToLifecycle();
        this.loading = loading;
    }

    /**
     * 统一加上进度条、线程调度等
     */
    @Override
    public ObservableSource<T> apply(Observable<T> upstream) {
        return upstream
                .throttleFirst(1, TimeUnit.SECONDS)//取1秒之内的最后一次,防止重复提交
                .subscribeOn(BaseScheduler.web())//在异步线程执行耗时操作，对上面的操作有用
                .doOnSubscribe(disposable -> {
                    if (loading != null && !loading.isShowing()) {
                        loading.show();
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread())//在主线程显示进度条，对上面的操作有用
                .compose(transformer)//绑定生命周期
                .onErrorResumeNext(throwable -> {
                    LogUtil.printException(throwable);
                    if (loading != null) {
                        loading.cancel();
                    }
                    return Observable.error(new ApiException(throwable));
                })
                //公共错误拦截
                .map(t -> {
                    if (loading != null) {
                        loading.cancel();
                    }
                    return t;
                })
                .observeOn(AndroidSchedulers.mainThread());//在主线程回调，对下面的操作有用
    }

}
